/**
 * 
 */
package net.ifunit.generate.task;

import java.io.File;
import java.net.URISyntaxException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * 
 * @author wy
 * @version v 0.1 2013-6-2 下午1:36:07 wy Exp $
 */
public class TaskUtil {

	/** 日志 */
	private static final Logger log = LoggerFactory.getLogger(TaskUtil.class);

	/** 参数 */
	private final static Map<String, String> propertiesMap = new LinkedHashMap<String, String>();

	/** 生成任务 */
	private final static Map<String, Task> taskMap = new LinkedHashMap<String, Task>();

	private static String[] tables = new String[] {};

	private static String tablePrefix = "";

	/**
	 * 获取生成的表
	 * 
	 * @return
	 */
	public static String[] getTables() {
		return tables;
	}

	/**
	 * 获取配置的属性
	 * 
	 * @return
	 */
	public static Map<String, String> getPropertiesmap() {
		return propertiesMap;
	}

	/**
	 * 获取任务
	 * 
	 * @return
	 */
	public static Map<String, Task> getTaskmap() {
		return taskMap;
	}

	/**
	 * 获取表前缀
	 * 
	 * @return
	 */
	public static String getTablePrefix() {
		return tablePrefix;
	}

	/**
	 * 获取任务列表
	 * 
	 * @return
	 */
	public static void load() {
		String xmlPath = null;
		try {
			xmlPath = Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath();
		} catch (URISyntaxException e) {

		}

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 设置验证
		factory.setValidating(true);
		// 由于我们只关心非空白元素，这里再加一条设置：
		// factory.setIgnoringElementContentWhitespace(true);
		DocumentBuilder builder = null;
		try {
			builder = factory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			throw new RuntimeException("创建xml解析错误", e);
		}
		builder.setErrorHandler(new ErrorHandler() {
			@Override
			public void warning(SAXParseException exception) throws SAXException {
				log.warn("解析xml-warning", exception);
			}

			@Override
			public void error(SAXParseException exception) throws SAXException {
				throw new RuntimeException("解析task.xml错误" + exception.getLineNumber() + "行,"
						+ exception.getColumnNumber() + "列");
			}

			@Override
			public void fatalError(SAXParseException exception) throws SAXException {
				log.warn("解析xml-fatalError", exception);
			}
		});
		String commandPath = xmlPath + "tasks.xml";
		log.info("当前class路径{}...", commandPath);
		Document doc = null;
		try {
			doc = builder.parse(new File(commandPath));
		} catch (Exception e) {
			throw new RuntimeException("加载tasks.xml出错", e);
		}
		doc.normalize();
		Element root = doc.getDocumentElement();
		String table = root.getAttribute("table");
		if (StringUtils.isBlank(table)) {
			throw new IllegalArgumentException("task.xml中table不能为空");
		}
		tables = table.split(",|;");
		String tPrefix = root.getAttribute("tablePrefix");
		if (StringUtils.isNotBlank(tPrefix)) {
			tablePrefix = tPrefix.trim();
		}

		NodeList propertyNode = root.getElementsByTagName("properties");
		if (propertyNode.getLength() > 0) {
			Element properties = (Element) propertyNode.item(0);
			NodeList propertyList = properties.getElementsByTagName("property");
			int length = propertyList.getLength();
			for (int i = 0; i < length; i++) {
				Element property = (Element) propertyList.item(i);
				String key = property.getAttribute("key");
				String value = property.getAttribute("value");
				if (key.trim().length() == 0) {
					continue;
				}
				propertiesMap.put(key.trim(), value);
			}
			log.info("加载property完毕");
		}

		NodeList taskList = root.getElementsByTagName("task");
		int length = taskList.getLength();
		for (int i = 0; i < length; i++) {
			Element element = (Element) taskList.item(i);
			String name = element.getAttribute("name");
			String genClass = element.getAttribute("class");
			String template = element.getAttribute("template");
			String suffix = element.getAttribute("suffix");
			String prefix = element.getAttribute("prefix");
			String ext = element.getAttribute("ext");
			String path = element.getAttribute("path");
			if (StringUtils.isBlank(name)) {
				throw new IllegalArgumentException("第" + i + "个task的name不能为空");
			}
			if (StringUtils.isBlank(genClass)) {
				throw new IllegalArgumentException("第" + i + "个task的genClass不能为空");
			}
			if (StringUtils.isBlank(template)) {
				throw new IllegalArgumentException("第" + i + "个task的template不能为空");
			}
			if (StringUtils.isBlank(ext)) {
				throw new IllegalArgumentException("第" + i + "个task的ext不能为空");
			}
			if (StringUtils.isBlank(path)) {
				throw new IllegalArgumentException("第" + i + "个task的path不能为空");
			}

			Map<String, String> map = new LinkedHashMap<String, String>();

			propertyNode = element.getElementsByTagName("property");
			if (propertyNode.getLength() > 0) {
				int propertyLength = propertyNode.getLength();
				for (int k = 0; k < propertyLength; k++) {
					Element property = (Element) propertyNode.item(k);
					String key = property.getAttribute("key");
					String value = property.getAttribute("value");
					if (key.trim().length() == 0) {
						continue;
					}
					map.put(key.trim(), value);
				}
			}

			Task task = new Task();

			String taskExt = ext.toLowerCase().trim();
			String taskName = name.trim();
			String taskPath = path.trim();
			String taskPrefix = prefix.trim();
			String taskSuffix = suffix.trim();
			String taskTemplate = template.trim();
			String genTask = genClass.trim();

			for (Entry<String, String> entry : propertiesMap.entrySet()) {
				taskExt = taskExt.replace("${" + entry.getKey() + "}", entry.getValue());
				taskName = taskName.replace("${" + entry.getKey() + "}", entry.getValue());
				taskPath = taskPath.replace("${" + entry.getKey() + "}", entry.getValue());
				taskPrefix = taskPrefix.replace("${" + entry.getKey() + "}", entry.getValue());
				taskSuffix = taskSuffix.replace("${" + entry.getKey() + "}", entry.getValue());
				taskTemplate = taskTemplate.replace("${" + entry.getKey() + "}", entry.getValue());
				genTask = genTask.replace("${" + entry.getKey() + "}", entry.getValue());
				for (Entry<String, String> entryMap : map.entrySet()) {
					entryMap.setValue(entryMap.getValue().replace("${" + entry.getKey() + "}", entry.getValue()));
				}
			}

			try {
				Class<?> clazz = Class.forName(genTask);
				Object object = clazz.newInstance();
				if (!(object instanceof GenerateTask)) {
					throw new IllegalArgumentException("第" + i + "个task的genClass的类型不正确");
				}
				task.setGenerateTask((GenerateTask) object);
			} catch (Exception e) {
				throw new IllegalArgumentException("第" + i + "个task的genClass初始化错误", e);
			}

			task.setExt(taskExt);
			task.setName(taskName);
			task.setPath(taskPath);
			task.setPrefix(taskPrefix);
			task.setProperties(map);
			task.setSuffix(taskSuffix);
			task.setTemplate(taskTemplate);
			taskMap.put(task.getName(), task);

		}
	}
}
